#include "AgentGroup.h"
#include "Agent.h"
#include "Factory.h"
#include "CameraManager.h"
#include "Game.h"
#include "DX11ErrorReport.h"

AgentGroup::AgentGroup()
{
	m_mazeCellSize = TheGame::Instance()->GetMaze()->GetCellSize();
	m_mazeSize = TheGame::Instance()->GetMaze()->GetGridSize();
	m_player = new Agent();
}

AgentGroup::~AgentGroup()
{
	if (m_player) delete m_player;
	for (int i = 0; i != m_agents.size(); i++)
	{
		delete m_agents[i];
	}
	m_agents.clear();
}

void AgentGroup::Draw()
{
	for (int i = 0; i != m_agents.size(); i++)
	{
		m_agents[i]->Draw();
	}
}

void AgentGroup::Update()
{
	D3DXVECTOR3 camPos = TheCameraManager::Instance()->GetCameraPos();
	
	camPos.x += m_mazeCellSize.x * (m_mazeSize.x * 0.5f);
	camPos.z += m_mazeCellSize.z * (m_mazeSize.y * 0.5f);

	m_player->SetPosition(camPos);

	for (int i = 0; i != m_agents.size(); i++)
	{
		m_agents[i]->Update();
	}
}

void AgentGroup::AddAgent(Agent* agent)
{
	m_agents.push_back(agent);
}

Neighbours AgentGroup::GetNeighbours(Agent* agent, float radius)
{
	Neighbours result;
	//radius *= radius;
	for (int i = 0; i != m_agents.size(); i++)
	{
		D3DXVECTOR3 vec = m_agents[i]->GetPosition() - agent->GetPosition();
		//float p2 = D3DXVec3Length(&agent->GetPosition());

		float distance = D3DXVec3LengthSq(&vec);

		// get distance from this agent to current iterator agent
		//float distance = l1 - l2;
		// if distance is less than radius, add to return vector
		//distance *= distance;
		if (distance < radius)
		{
			result.push_back(m_agents[i]);
		}
	}
	return result;
}

void AgentGroup::DrawMiniMapElements()
{
	for (int i = 0; i != m_agents.size(); i++)
	{
		m_agents[i]->DrawMiniMapElements();
	}
}

bool AgentGroup::Load(File* F)
{
	int numOfAgents = -1;

	if (!F->GetInteger(&numOfAgents))
	{
		DX11ErrorMsg(L"Expected number of agents", L"AgentGroup::Load()", MB_OK);
		return false;
	}

	for (int i = 0; i != numOfAgents; i++)
	{
		Agent* tempAgent = new Agent;

		float maxForce;
		D3DXVECTOR3 maxVel;
		float mass;
		float aggressiveness;
		int roomNum = -1;
		int randRoom = rand() % TheGame::Instance()->GetMaze()->GetRoomCells()[0].size();

		if (!F->GetFloat(&maxForce))
		{
			DX11ErrorMsg(L"Expected max force", L"AgentGroup::Load()", MB_OK);
			return false;
		}
		if (!F->GetD3DXVECTOR3(&maxVel))
		{
			DX11ErrorMsg(L"Expected max velocity", L"AgentGroup::Load()", MB_OK);
			return false;
		}
		if (!F->GetFloat(&mass))
		{
			DX11ErrorMsg(L"Expected mass", L"AgentGroup::Load()", MB_OK);
			return false;
		}
		if (!F->GetFloat(&aggressiveness))
		{
			DX11ErrorMsg(L"Expected agressiveness", L"AgentGroup::Load()", MB_OK);
			return false;
		}
		if (!F->GetInteger(&roomNum))
		{
			DX11ErrorMsg(L"Expected room number", L"AgentGroup::Load()", MB_OK);
			return false;
		}

		tempAgent->SetTarget(m_player);
		tempAgent->SetGroup(this);
		tempAgent->SetMaxForce(maxForce);
		tempAgent->SetMaxVel(maxVel);
		tempAgent->SetMass(mass);
		tempAgent->SetAggressiveness(aggressiveness);
		CellPosition c1 = TheGame::Instance()->GetMaze()->GetRoomCells()[roomNum][randRoom];
		tempAgent->SetPosition(TheGame::Instance()->GetMaze()->GetCellPos(c1));
	
		m_agents.push_back(tempAgent);
	}

	

	/*
		tempAgent2->SetTarget(m_player);
		tempAgent2->SetMaxForce(5.0f);
		tempAgent2->SetMaxVel(D3DXVECTOR3(1.0f, 1.0f, 1.0f));
		tempAgent2->SetMass(2.5f);
		c1 = TheGame::Instance()->GetMaze()->GetRoomCells()[0][21];
		tempAgent2->SetPosition(TheGame::Instance()->GetMaze()->GetCellPos(c1));
		tempAgent2->SetGroup(this);*/

	return true;
}

const char* AgentGroup::GetTypeName() const
{
	return "AgentGroup";
}

GameObject* CreateAgentGroup()
{
	return new AgentGroup;
}

static bool b = TheGameObjectFactory::Instance()->AddType("AgentGroup", CreateAgentGroup);